package com.ruoyi.project.comp.work.controller;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.ruoyi.common.oss.OSSUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.comp.file.domain.CompWorkFile;
import com.ruoyi.project.comp.file.service.ICompWorkFileService;
import com.ruoyi.project.tool.OssFileNameUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.project.comp.work.domain.CompWork;
import com.ruoyi.project.comp.work.service.ICompWorkService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.page.TableDataInfo;

import javax.servlet.http.HttpServletResponse;

/**
 * 作品Controller
 * 
 * @author ruoyi
 * @date 2025-11-02
 */
@Controller
@RequestMapping("/comp/work")
public class CompWorkController extends BaseController
{

    private static final Logger log = LoggerFactory.getLogger(CompWorkController.class);

    private String prefix = "comp/work";

    @Autowired
    private ICompWorkService compWorkService;

    @Autowired
    private ICompWorkFileService compWorkFileService;

    @Autowired
    private OSSUtils ossUtils;


    @RequiresPermissions("comp:work:view")
    @GetMapping()
    public String work()
    {
        return prefix + "/work";
    }

    /**
     * 查询作品列表
     */
    @RequiresPermissions("comp:work:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(CompWork compWork)
    {
        startPage();
        List<CompWork> list = compWorkService.selectCompWorkList(compWork);
        return getDataTable(list);
    }

    /**
     * 导出作品列表
     */
    @RequiresPermissions("comp:work:export")
    @Log(title = "作品", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(CompWork compWork)
    {
        List<CompWork> list = compWorkService.selectCompWorkList(compWork);
        ExcelUtil<CompWork> util = new ExcelUtil<CompWork>(CompWork.class);
        return util.exportExcel(list, "作品数据");
    }

    /**
     * 新增作品
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存作品
     */
//    @RequiresPermissions("comp:work:add")
//    @Log(title = "作品", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(@RequestBody CompWork compWork)
    {
        return toAjax(compWorkService.insertCompWork(compWork));
    }

    /**
     * 修改作品
     */
    @RequiresPermissions("comp:work:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        CompWork compWork = compWorkService.selectCompWorkById(id);
        mmap.put("compWork", compWork);
        return prefix + "/edit";
    }

    /**
     * 修改保存作品
     */
    @RequiresPermissions("comp:work:edit")
    @Log(title = "作品", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(CompWork compWork)
    {
        return toAjax(compWorkService.updateCompWork(compWork));
    }

    /**
     * 删除作品
     */
    @RequiresPermissions("comp:work:remove")
    @Log(title = "作品", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(compWorkService.deleteCompWorkByIds(ids));
    }




    @PostMapping("/batchPass")
    @ResponseBody
    public AjaxResult batchPass(@RequestParam("ids") String ids) {
        try {
            // 1. 校验参数
            if (ids == null || ids.trim().isEmpty()) {
                return AjaxResult.error("请选择需要处理的数据");
            }

            String[] idArray = ids.split(",");
            for (int i = 0; i < idArray.length; i++) {
                String id = idArray[i];
                CompWork work = new CompWork();
                work.setId(Long.valueOf(id));
                work.setStatus(1L);
                compWorkService.updateCompWork(work);
            }
           return AjaxResult.success("操作成功");
        } catch (Exception e) {
            return AjaxResult.error("操作失败：" + e.getMessage());
        }
    }



    @PostMapping("/batchReject")
    @ResponseBody
    public AjaxResult batchReject(@RequestParam("ids") String ids) {
        try {
            // 1. 校验参数
            if (ids == null || ids.trim().isEmpty()) {
                return AjaxResult.error("请选择需要处理的数据");
            }

            String[] idArray = ids.split(",");
            for (int i = 0; i < idArray.length; i++) {
                String id = idArray[i];
                CompWork work = new CompWork();
                work.setId(Long.valueOf(id));
                work.setStatus(2L);
                compWorkService.updateCompWork(work);
            }
            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            return AjaxResult.error("操作失败：" + e.getMessage());
        }
    }

    @PostMapping("/batchDelete")
    @ResponseBody
    public AjaxResult batchDelete(@RequestParam("ids") String ids) {
        try {
            // 1. 校验参数
            if (ids == null || ids.trim().isEmpty()) {
                return AjaxResult.error("请选择需要处理的数据");
            }
            String[] idArray = ids.split(",");
            for (int i = 0; i < idArray.length; i++) {
                String id = idArray[i];
                compWorkService.deleteCompWorkById(Long.valueOf(id));
            }
            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            return AjaxResult.error("操作失败：" + e.getMessage());
        }
    }

    @PostMapping("/batchDownload1")
    public void batchDownload1(@RequestParam("ids") String ids, HttpServletResponse response) {
        try {
            if (StringUtils.isEmpty(ids.trim())) {
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":500,\"msg\":\"请选择需要处理的数据\"}");
                return;
            }
            String[] idArray = ids.split(",");
            List<Long> workIdList = new ArrayList<>(); // 收集有效作品ID，用于后续查文件
            for (String idStr : idArray) {
                if (StringUtils.isEmpty(idStr.trim())) {
                    continue; // 跳过空ID
                }
                Long workId = Long.valueOf(idStr.trim());
                workIdList.add(workId); // 加入有效ID列表
            }

            if (workIdList.isEmpty()) {
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":500,\"msg\":\"无有效作品可下载\"}");
                return;
            }

            List<String> ossObjectKeys = new ArrayList<>();
            for (Long workId : workIdList) {
                CompWork compWork = compWorkService.selectCompWorkById(workId);
                CompWorkFile queryFile = new CompWorkFile();
                queryFile.setWorkId(workId); // 按作品ID查询关联文件
                List<CompWorkFile> fileList = compWorkFileService.selectCompWorkFileList(queryFile);
                for (CompWorkFile file : fileList) {
                    String objectKey = file.getObjectKey(); // 替换为你的实际字段名（如filePath/ossKey）
                    if (StringUtils.isNotEmpty(objectKey)) {
                        ossObjectKeys.add(objectKey);
                    }
                }
            }
            if (ossObjectKeys.isEmpty()) {
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":500,\"msg\":\"所选作品无关联文件可下载\"}");
                return;
            }
            String zipFileName = "作品文件批量下载.zip"; // 自定义ZIP文件名
            ossUtils.batchDownloadAndZip(ossObjectKeys, zipFileName, response);
        } catch (NumberFormatException e) {
            // 处理ID格式错误（如非数字）
            handleErrorResponse(response, "ID格式错误：" + e.getMessage());
        } catch (Exception e) {
            // 处理其他异常（如OSS连接失败、数据库异常）
            handleErrorResponse(response, "操作失败：" + e.getMessage());
        }
    }


    /**
     * 统一处理错误响应（避免流冲突，返回JSON格式错误信息）
     */
    private void handleErrorResponse(HttpServletResponse response, String errorMsg) {
        try {
            response.setContentType("application/json;charset=UTF-8");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500状态码
            // 按AjaxResult的格式返回错误信息（保持前端统一解析）
            response.getWriter().write(String.format("{\"code\":500,\"msg\":\"%s\"}", errorMsg));
        } catch (Exception ex) {
            ex.printStackTrace(); // 日志记录错误（建议替换为log.error）
        }
    }


    @RequestMapping("/batchDownload")
    public void batchDownload(@RequestParam("ids") String ids, HttpServletResponse response) {
        // 总压缩包输出流（直接写入响应）
        try (ZipOutputStream totalZipOs = new ZipOutputStream(response.getOutputStream())) {
            // 1. 基础参数校验
            if (StringUtils.isEmpty(ids.trim())) {
                writeErrorResponse(response, "请选择需要处理的数据");
                return;
            }

            // 2. 解析作品ID，筛选有效ID
            String[] idArray = ids.split(",");
            List<Long> validWorkIds = new ArrayList<>();
            for (String idStr : idArray) {
                if (StringUtils.isEmpty(idStr.trim())) continue;
                validWorkIds.add(Long.valueOf(idStr.trim()));
            }
            if (validWorkIds.isEmpty()) {
                writeErrorResponse(response, "无有效作品可下载");
                return;
            }

            // 3. 配置总压缩包响应头
            response.setContentType("application/zip");
            String totalZipName = URLEncoder.encode("作品文件总压缩包.zip", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + totalZipName + "\"");

            // 4. 遍历每个作品，生成独立压缩包并加入总压缩包
            for (Long workId : validWorkIds) {
                // 4.1 获取当前作品信息（用于生成独立压缩包名称）
                CompWork compWork = compWorkService.selectCompWorkById(workId);
                String workName = compWork != null && StringUtils.isNotEmpty(compWork.getWorkName())
                        ? compWork.getWorkName()
                        : "作品_" + workId; // 默认名称（避免空名）

                // 4.2 查询当前作品关联的OSS文件路径
//                CompWorkFile queryFile = new CompWorkFile();
//                queryFile.setWorkId(workId);
//                List<CompWorkFile> fileList = compWorkFileService.selectCompWorkFileList(queryFile);
                List<String> singleWorkObjectKeys = new ArrayList<>();
//                for (CompWorkFile file : fileList) {
//                    if (StringUtils.isNotEmpty(file.getObjectKey())) {
//                        singleWorkObjectKeys.add(file.getObjectKey());
//                    }
//                }




                String workScript = compWork.getWorkScript();
                String workVideo1 = compWork.getWorkVideo1();
                String workVideo2 = compWork.getWorkVideo2();
                String workSpeech = compWork.getWorkSpeech();
                String workOther = compWork.getWorkOther();


                String workScriptOss = OssFileNameUtil.getFileName(workScript);
                if (StringUtils.isNotEmpty(workScriptOss)) {
                    singleWorkObjectKeys.add(workScriptOss);
                }
                String workVideo1Oss = OssFileNameUtil.getFileName(workVideo1);
                if (StringUtils.isNotEmpty(workVideo1Oss)) {
                    singleWorkObjectKeys.add(workVideo1Oss);
                }
                String workVideo2Oss = OssFileNameUtil.getFileName(workVideo2);
                if (StringUtils.isNotEmpty(workVideo2Oss)) {
                    singleWorkObjectKeys.add(workVideo2Oss);
                }
                String workSpeechOss = OssFileNameUtil.getFileName(workSpeech);
                if (StringUtils.isNotEmpty(workSpeechOss)) {
                    singleWorkObjectKeys.add(workSpeechOss);
                }
                String workOtherOss = OssFileNameUtil.getFileName(workOther);
                if (StringUtils.isNotEmpty(workOtherOss)) {
                    singleWorkObjectKeys.add(workOtherOss);
                }



                // 4.3 若当前作品无文件，跳过（可选：也可生成空压缩包）
                if (singleWorkObjectKeys.isEmpty()) {
                    log.warn("作品[ID:{}，名称:{}]无关联文件，跳过独立压缩包生成", workId, workName);
                    continue;
                }

                // 4.4 生成当前作品的独立压缩包（内存流，无需本地文件）
                ByteArrayOutputStream singleZipBaos = new ByteArrayOutputStream();
                try (ZipOutputStream singleZipOs = new ZipOutputStream(singleZipBaos)) {
                    // 调用OSS工具类核心逻辑：将当前作品的文件写入独立压缩包
                    ossUtils.writeWorkFilesToZip(singleWorkObjectKeys, singleZipOs);
                }

                // 4.5 将独立压缩包加入总压缩包（作为一个ZipEntry）
                String singleZipEntryName = workName + ".zip"; // 独立压缩包在总包中的名称
                ZipEntry singleZipEntry = new ZipEntry(singleZipEntryName);
                totalZipOs.putNextEntry(singleZipEntry);

                // 4.6 将独立压缩包的内存流写入总压缩包
                try (ByteArrayInputStream singleZipBais = new ByteArrayInputStream(singleZipBaos.toByteArray())) {
                    byte[] buffer = new byte[1024 * 8];
                    int len;
                    while ((len = singleZipBais.read(buffer)) != -1) {
                        totalZipOs.write(buffer, 0, len);
                    }
                }
                totalZipOs.closeEntry(); // 关闭当前独立压缩包的Entry
                log.info("作品[ID:{}，名称:{}]的独立压缩包已加入总压缩包", workId, workName);
            }

            // 5. 完成总压缩包写入
            totalZipOs.finish();
            log.info("总压缩包生成完成，共包含{}个作品的独立压缩包", validWorkIds.size());

        } catch (NumberFormatException e) {
            writeErrorResponse(response, "ID格式错误：" + e.getMessage());
        } catch (Exception e) {
            writeErrorResponse(response, "操作失败：" + e.getMessage());
        }
    }

    /**
     * 写入错误响应（JSON格式，避免流冲突）
     */
    private void writeErrorResponse(HttpServletResponse response, String msg) {
        try {
            response.setContentType("application/json;charset=UTF-8");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write(String.format("{\"code\":500,\"msg\":\"%s\"}", msg));
        } catch (IOException e) {
            log.error("写入错误响应失败", e);
        }
    }


    @GetMapping("/detail/{id}")
    public String detail(@PathVariable("id") Long id, ModelMap mmap)
    {
        CompWork compWork = compWorkService.selectCompWorkById(id);
        mmap.put("compWork", compWork);
        return "comp/work/edit";
    }

}
